package com.coral.login.module.maya.ios;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.message.BasicNameValuePair;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONObject;
import com.coral.login.common.result.IResult;
import com.coral.login.domain.entity.OrderInfo;
import com.coral.login.domain.entity.OrderStatusEnum;
import com.coral.login.module.core.AbstractController;
import com.coral.login.module.core.annotation.ParameterMapping;
import com.coral.login.module.core.base.IExchargeParam;
import com.coral.login.module.core.support.AuthResult;
import com.coral.login.module.core.support.ErrorCodeEnum;
import com.coral.login.module.core.support.ExchargeResult;
import com.coral.login.module.core.support.ResultCode;
import com.coral.login.module.maya.android.param.MayaExchargeParam;
import com.coral.login.module.maya.android.param.MayaLoginParam;
import com.coral.login.module.maya.ios.param.MayaIOSExchargeParam;
import com.coral.login.module.maya.ios.param.MayaIOSLoginParam;
import com.coral.login.module.maya.ios.result.MayaIOSExchargeResult;
import com.coral.login.util.HttpClientUtil;
import com.coral.login.util.MD5;
import com.google.common.collect.Maps;

/**
 * 用于玛雅iossdk接入
 * @auth Jeremy
 * @date 2019年11月20日上午9:13:16
 */
@RestController
@RequestMapping("/maya/ios")
@ParameterMapping(loginParam = MayaLoginParam.class, exchargeParam = MayaExchargeParam.class)
public class MayaIOSController extends AbstractController {
	
	private static final Logger LOGGER = LogManager.getLogger(MayaIOSController.class);

	/**
	 *  1. 将所有参数按a-z 排序
	 *	2. 排序后,拼接成 key1=value1&key2=value2…&appkey=key
	 *  3. md5(key1=value1&key2=value2…&key=paykey) 
	 */
	@Override
	public IResult sdkLogin(Object object) {
		MayaIOSLoginParam param = (MayaIOSLoginParam) object;
		String time = String.valueOf((System.currentTimeMillis() / 1000));
		List<BasicNameValuePair> list = new ArrayList<>();
		list.add(new BasicNameValuePair("userid", param.getUserid()));// 游戏ID，sdk方提供
		list.add(new BasicNameValuePair("appid", param.getAppid()));// 用户ID，SDK登录时返回
		list.add(new BasicNameValuePair("gameid", param.getGameid()));// 游戏ID，sdk方提供
		list.add(new BasicNameValuePair("accesstoken", param.getAccesstoken())); // 用户令牌，SDK登录时返回
		list.add(new BasicNameValuePair("time", time)); // 当前时间戳(秒)
		String localSign = localSign(list);
		list.add(new BasicNameValuePair("sign", localSign)); // 签名
		try {
			String ret = HttpClientUtil.doPost(MayaIOSConfig.requestUrl, list);
//			String ret = HttpClientUtil.doHttpPost(MayaConfig.requestUrl, param, ContentType.APPLICATION_FORM_URLENCODED);
			if (StringUtils.isBlank(ret)) {
				LOGGER.info("login error, ret is null or empty");
				return AuthResult.build(ErrorCodeEnum.ERROR_SIGN_NULL);
			}
			@SuppressWarnings("unchecked")
			Map<String, String> retMap = JSONObject.parseObject(ret, Map.class);
			String code = String.valueOf(retMap.get("code"));
			LOGGER.info("login info, localSign:{}, ret:{}, param:{}", localSign, ret, list);
			// 状态码，1:成功，其余失败
			if (code != null && code.equals(ResultCode.CODE_1))
				return AuthResult.build(ErrorCodeEnum.SUCCESS);
			else {
				LOGGER.info("login error, ret:{}, localSign:{}", ret, localSign);
				return AuthResult.build(ErrorCodeEnum.ERROR_SIGN_ERROR);
			}
		} catch (Exception e) {
			e.printStackTrace();
			LOGGER.error("login error, localSign:{}", localSign);
			return AuthResult.build(ErrorCodeEnum.ERROR_SIGN_NULL);
		}
	}
	
	/**
	 * sdk充值验签
	 */
	@Override
	public IResult sdkExcharge(IExchargeParam param, OrderInfo orderInfo) {
		//订单如果已经处理过,游戏方返回失败, 渠道方返回成功
		if (orderInfo.getState() == OrderStatusEnum.Order_Exchanged_Success.getStatus()) {
			LOGGER.info("重复提交订单, orderId:{}, actorId:{}", orderInfo.getOrderId(), orderInfo.getActorId());
			return ExchargeResult.build(ErrorCodeEnum.ERROR_ORDER_REPEAT, ResultCode.CODE_SUCCESS);
		}
		IResult result = null;
		MayaIOSExchargeParam exchargeParam = (MayaIOSExchargeParam) param;
		Map<String, String> objMap = MayaIOSConfig.objToTreeMap(exchargeParam, "sign");
		String localSign = getLocalSignByMap(objMap, "key="+ MayaIOSConfig.paykey);
		// 验签
		if (StringUtils.equals(localSign, exchargeParam.getSign())) {
			result = ExchargeResult.build(ErrorCodeEnum.SUCCESS, ResultCode.CODE_SUCCESS);
		} else {
			result = ExchargeResult.build(ErrorCodeEnum.IllEGAL_PARAMS, ResultCode.CODE_FAILURE);
		}
		LOGGER.info("支付验签, localSign:{}, remoteSign:{}, exchargeParam:{}, result:{}", localSign, exchargeParam.getSign(), exchargeParam, result);
		return result;
	}
	

	/**
	 * 生成本地签名
	 * @param list
	 * @return  
	 * @return String  
	 * @date 2019年10月28日下午4:54:02
	 */
	private String localSign(List<BasicNameValuePair> list) {
		Map<String, String> objMap = Maps.newTreeMap();
		for (BasicNameValuePair nameValuePair : list) {
			objMap.put(nameValuePair.getName(), nameValuePair.getValue());
		}
		String localSign = getLocalSignByMap(objMap, "key="+MayaIOSConfig.paykey);
		return localSign;
	}
	
	
//	@Override
//	public String buildResult(IResult result) {
//		return MayaIOSExchargeResult.build(result.code(), result.tips()).result();
//	}
	
	/**
	 * 公共生成加密串方法
	 * @style key1=value1&key2=value2
	 * @param map
	 * @return
	 */
	public String getLocalSignByMap(Map<String, String> map, String... extras) {
		StringBuilder url = new StringBuilder();
		for (Map.Entry<String, String> entry : map.entrySet()) {
			url.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
		}
		for (String extra : extras) {
			url.append(extra).append("&");
		}
		url.deleteCharAt(url.length() - 1);
		// md5加密
		String mySign = MD5.digest(url.toString(), true);
		return mySign;
	}
}
